/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { DfuService } from './DfuService'
import { BaseDfuImpl } from './BaseDfuImpl'
import { DfuBaseService } from './DfuBaseService'
import { ButtonlessDfuWithBondSharingImpl } from './ButtonlessDfuWithBondSharingImpl'
import { ButtonlessDfuWithoutBondSharingImpl } from './ButtonlessDfuWithoutBondSharingImpl'
import { SecureDfuImpl } from './SecureDfuImpl'
import { LegacyButtonlessDfuImpl } from './LegacyButtonlessDfuImpl'
import { LegacyDfuImpl } from './LegacyDfuImpl'
import { ExperimentalButtonlessDfuImpl } from './ExperimentalButtonlessDfuImpl'

import ble from '@ohos.bluetooth.ble';
import hilog from '@ohos.hilog';
import { DfuCallback } from './DfuCallback'

export class DfuServiceProvider implements DfuCallback {
  private TAG: string = 'DfuServiceProvider';
  private DOMAIN: number = 0x8632;
  private mImpl: BaseDfuImpl;
  private mPaused: boolean;
  private mAborted: boolean;

  public async getServiceImpl(service: DfuBaseService, gatt: ble.GattClientDevice): Promise<BaseDfuImpl> {
    try {
      let gsList: Array<ble.GattService> = await gatt.getServices()
      hilog.debug(this.DOMAIN, this.TAG, `GattService: ${JSON.stringify(gsList)}`)

      this.mImpl = new ButtonlessDfuWithBondSharingImpl(service);
      if (await this.mImpl.isClientCompatible(gsList)) {
        return this.mImpl;
      }

      this.mImpl = new ButtonlessDfuWithoutBondSharingImpl(service);
      if (await this.mImpl.isClientCompatible(gsList)) {
        return this.mImpl;
      }

      this.mImpl = new SecureDfuImpl(service);
      if (await this.mImpl.isClientCompatible(gsList)) {
        return this.mImpl;
      }

      this.mImpl = new LegacyButtonlessDfuImpl(service);
      if (await this.mImpl.isClientCompatible(gsList)) {
        return this.mImpl;
      }

      this.mImpl = new LegacyDfuImpl(service);
      if (await this.mImpl.isClientCompatible(gsList)) {
        return this.mImpl;
      }

    } catch (e) {
      hilog.error(this.DOMAIN, this.TAG, `getServiceImpl error: ${JSON.stringify(e)}`)
    }
    return null;
  };

  public getGattCallback() {
    return;
  }

  public onBondStateChanged(state: number) {
    if (this.mImpl != null) {
      this.mImpl.onBondStateChanged(state);
    }
  }

  public pause() {
    this.mPaused = true;
  }

  public resume() {
    this.mPaused = false;
  }

  public abort() {
    this.mAborted = true;
    if (this.mImpl != null) {
      this.mImpl.abort();
    }
  }
}